﻿using System;
using System.IO;
using System.IO.Pipes;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using UMC.Net;

namespace UMC.Host
{

    class HttpBridgeMime : HttpMime
    {
        HttpBridgeClient client;
        public HttpBridgeMime(int pid, HttpBridgeClient client)
        {
            this.client = client;
            this.pid = pid;
        }
        internal int pid;
        public override string Host => "127.0.0.1";

        public override string RemoteIpAddress => "127.0.0.1";

        public override int Id => pid;

        public override void Dispose()
        {
            _webSocket?.Dispose();
            client.Remove(this.pid);
        }
        public void WebSocket(byte[] buffer, int offset, int count)
        {
            try
            {
                _webSocket?.Write(buffer, offset, count);
            }
            catch
            {
                client.Write(this.pid, new byte[0], 0, 0);
                this.Dispose();
            }
        }
        public override void Subscribe(HttpMimeRequest webRequest)
        {
            this.OutText(500, "穿透不支持UMC数据订阅协议");
        }

        protected override void WebSocket(NetContext context)
        {
            if (context.Tag is HttpWebRequest)
            {
                var webr = context.Tag as HttpWebRequest;
                this.WebSocket(webr);
            }
        }
        async void WebSocket(HttpWebRequest webRequest)
        {
            try
            {
                var url = webRequest.RequestUri;


                var client = new Socket(SocketType.Stream, ProtocolType.Tcp);

                await client.ConnectAsync(url.Host, url.Port);


                if (url.Scheme == "https")
                {
                    SslStream ssl = new SslStream(new NetworkStream(client, true), false, (sender, certificate, chain, sslPolicyErrors) => true);
                    await ssl.AuthenticateAsClientAsync(url.Host, null, SslProtocols.None, false);
                    var ws = new HttpsWebSocket(this, ssl);
                    await ssl.WriteAsync(ws.buffer, 0, UMC.Net.NetHttpResponse.Header(webRequest, ws.buffer));

                    _webSocket = ws;// new HttpsWebSocket(this, ssl);
                }
                else
                {
                    var ws = new HttpWebSocket(this, client);
                    client.Send(ws.buffer, 0, UMC.Net.NetHttpResponse.Header(webRequest, ws.buffer), SocketFlags.None);
                    _webSocket = ws;// new HttpWebSocket(this, client);

                }

            }
            catch (Exception ex)
            {
                this.OutText(500, ex.ToString());
                this.Dispose();
            }
        }
        WebSocket _webSocket;
        public override void OutputFinish()
        {

        }
        public override void Write(byte[] buffer, int offset, int count)
        {
            if (count > 0)
            {

                client.Write(this.pid, buffer, offset, count);
            }
        }
    }
}

